﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Messaging;
using Miris.HumanMilkAnalyser.Service.Shared;
using Miris.HumanMilkAnalyser.WPF.Model;
using Miris.HumanMilkAnalyser.WPF.Shared;

namespace Miris.HumanMilkAnalyser.WPF.ViewModel
{
    public class PatientQuickSearchViewModel : MyViewModelBase
    {
        public const string GoToNextPageMessageToken = "PatientQuickSearchGoToNextPageMessage";

        /// <summary>
        /// Initializes a new instance of the PatientQuickSearchViewModel class.
        /// </summary>
        public PatientQuickSearchViewModel(IDataService dataService)
            : base(dataService) { }

        public override void ResetProperties()
        {
            base.ResetProperties();

            PatientNumber = string.Empty;
            MotherName = string.Empty;
            BabyName = string.Empty;
            PatientList.Clear();
        }

        /// <summary>
        /// The <see cref="PatientNumber" /> property's name.
        /// </summary>
        public const string PatientNumberPropertyName = "PatientNumber";

        private string _patientNumber = string.Empty;

        /// <summary>
        /// Sets and gets the PatientNumber property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public string PatientNumber
        {
            get
            {
                return _patientNumber;
            }

            set
            {
                if (_patientNumber == value)
                {
                    return;
                }

                RaisePropertyChanging(PatientNumberPropertyName);
                _patientNumber = value;
                RaisePropertyChanged(PatientNumberPropertyName);
            }
        }

        /// <summary>
        /// The <see cref="MotherName" /> property's name.
        /// </summary>
        public const string MotherNamePropertyName = "MotherName";

        private string _motherName = string.Empty;

        /// <summary>
        /// Sets and gets the MotherName property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public string MotherName
        {
            get
            {
                return _motherName;
            }

            set
            {
                if (_motherName == value)
                {
                    return;
                }

                RaisePropertyChanging(MotherNamePropertyName);
                _motherName = value;
                RaisePropertyChanged(MotherNamePropertyName);
            }
        }

        /// <summary>
        /// The <see cref="BabyName" /> property's name.
        /// </summary>
        public const string BabyNamePropertyName = "BabyName";

        private string _babyName = string.Empty;

        /// <summary>
        /// Sets and gets the BabyName property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public string BabyName
        {
            get
            {
                return _babyName;
            }

            set
            {
                if (_babyName == value)
                {
                    return;
                }

                RaisePropertyChanging(BabyNamePropertyName);
                _babyName = value;
                RaisePropertyChanged(BabyNamePropertyName);
            }
        }

        /// <summary>
        /// The <see cref="SelectedPatient" /> property's name.
        /// </summary>
        public const string SelectedPatientPropertyName = "SelectedPatient";

        private PatientQuickSearchResultItemViewModel _selectedPatient = null;

        /// <summary>
        /// Sets and gets the SelectedPatient property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public PatientQuickSearchResultItemViewModel SelectedPatient
        {
            get
            {
                return _selectedPatient;
            }

            set
            {
                if (_selectedPatient == value)
                {
                    return;
                }

                RaisePropertyChanging(SelectedPatientPropertyName);
                _selectedPatient = value;
                RaisePropertyChanged(SelectedPatientPropertyName);
            }
        }

        /// <summary>
        /// The <see cref="PatientList" /> property's name.
        /// </summary>
        public const string PatientListPropertyName = "PatientList";

        private ObservableCollection<PatientQuickSearchResultItemViewModel> _patientList = 
            new ObservableCollection<PatientQuickSearchResultItemViewModel>();

        /// <summary>
        /// Sets and gets the PatientList property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public ObservableCollection<PatientQuickSearchResultItemViewModel> PatientList
        {
            get
            {
                return _patientList;
            }

            set
            {
                if (_patientList == value)
                {
                    return;
                }

                RaisePropertyChanging(PatientListPropertyName);
                _patientList = value;
                RaisePropertyChanged(PatientListPropertyName);
            }
        }

        private RelayCommand _searchCommand;

        /// <summary>
        /// Gets the SearchCommand.
        /// </summary>
        public RelayCommand SearchCommand
        {
            get
            {
                return _searchCommand ?? (_searchCommand = new RelayCommand(
                    ExecuteSearchCommand));
            }
        }

        private void ExecuteSearchCommand()
        {
            try
            {
                var analysisResultService = ServiceFactory.CreateAnalysisResultService();
                var patientService = ServiceFactory.CreatePatientService();
                var matchedPatients = patientService.Query(p =>
                    (PatientNumber.Length == 0 || p.Number.ToLower().Contains(PatientNumber.ToLower())) &&
                    (MotherName.Length == 0 || p.MotherName.Contains(MotherName)) &&
                    (BabyName.Length == 0 || p.BabyName.Contains(BabyName))).OrderByDescending(p => p.CreateOn).ToList();

                PatientList.Clear();

                for (int i = 0; i < matchedPatients.Count; i++)
                {
                    var lastTest = analysisResultService.GetLastAnalysisResult(matchedPatients[i].Number);

                    PatientList.Add(new PatientQuickSearchResultItemViewModel(null)
                    {
                        SequenceNumber = i + 1,
                        PatientNumber = matchedPatients[i].Number,
                        MotherName = matchedPatients[i].MotherName,
                        BabyName = matchedPatients[i].BabyName,
                        LastTestDateDisplay = lastTest == null ? "N/A" : lastTest.TestDate.ToString(GeneralUtility.LongDateTimeFormat),
                        TestCount = analysisResultService.GetAllAnalysisCount(matchedPatients[i].Number)
                    });
                }
            }
            catch (Exception ex)
            {
                RequestDisplayErrorMessage(ex.Message);
            }
        }

        private RelayCommand _nextCommand;

        /// <summary>
        /// Gets the NextCommand.
        /// </summary>
        public RelayCommand NextCommand
        {
            get
            {
                return _nextCommand
                    ?? (_nextCommand = new RelayCommand(
                                          () =>
                                          {
                                              // Send GoToNextPageMessage to PatientQuickSearchPage.
                                              Messenger.Default.Send<string>(SelectedPatient.PatientNumber, GoToNextPageMessageToken);
                                          },
                                          () => SelectedPatient != null));
            }
        }
    }
}
